home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1996 #1
/
Amiga Plus CD - 1996 - No. 1.iso
/
pd
/
netz
/
xbtx_v1.1
/
iorawserial.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-26
|
8KB
|
400 lines
/*
** $Id: IORawSerial.cpp 1.3 1995/09/26 19:45:11 olsen Exp olsen $
**
** :ts=4
*/
/*
* Copyright © 1995 by Olaf Barthel, All Rights Reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software has not been validated by the ``Bundesamt fuer Zulassungen in
* der Telekommunikation'' of the ``Deutsche Bundepost Telekom'' and thus
* must not be used for accessing the BTX-Network of the Telekom in Germany.
*
* Diese Software hat keine Zulassung durch das Bundesamt fuer Zulassungen in
* der Telekommunikation der Deutschen Bundespost Telekom und darf daher nicht
* am Netz der Deutschen Bundespost Telekom in Deutschland betrieben werden.
*/
#include "IORawSerial.hpp"
#include <exec/memory.h>
#include <exec/errors.h>
#include <devices/serial.h>
#include <devices/timer.h>
#include <hardware/cia.h>
#include <clib/exec_protos.h>
#ifdef __SASC
#include <pragmas/exec_pragmas.h>
extern struct ExecBase *SysBase;
#endif // _SASC
#include <string.h>
#include <stdio.h>
VOID IORawSerial::StopRead(VOID)
{
if(Valid && Reading)
{
if(!CheckIO((struct IORequest *)ReadRequest))
AbortIO((struct IORequest *)ReadRequest);
WaitIO((struct IORequest *)ReadRequest);
Reading = FALSE;
}
}
VOID IORawSerial::StartRead(VOID)
{
if(Valid)
{
StopRead();
ReadRequest->IOSer.io_Command = CMD_READ;
ReadRequest->IOSer.io_Data = &SingleChar;
ReadRequest->IOSer.io_Length = 1;
SetSignal(0,ReadMask);
SendIO((struct IORequest *)ReadRequest);
Reading = TRUE;
}
}
BYTE IORawSerial::WaitRead(VOID)
{
BYTE Error;
if(Valid)
{
if(Reading)
{
Error = WaitIO((struct IORequest *)ReadRequest);
Reading = FALSE;
}
else
Error = 0;
}
else
Error = IOERR_OPENFAIL;
return(Error);
}
VOID IORawSerial::Close(VOID)
{
if(Valid)
{
StopRead();
StopTime();
CloseDevice((struct IORequest *)TimeRequest);
DeleteIORequest((struct IORequest *)TimeRequest);
DeleteMsgPort(TimePort);
CloseDevice((struct IORequest *)ReadRequest);
DeleteIORequest((struct IORequest *)ReadRequest);
FreeVec(WriteRequest);
DeleteMsgPort(WritePort);
DeleteMsgPort(ReadPort);
Valid = FALSE;
}
}
LONG IORawSerial::Open(CONST STRPTR Channel,ULONG Unit,ULONG Baud,BOOL RTS_CTS)
{
if(ReadPort = CreateMsgPort())
{
ReadMask = 1UL << ReadPort->mp_SigBit;
if(WritePort = CreateMsgPort())
{
if(ReadRequest = (struct IOExtSer *)CreateIORequest(ReadPort,sizeof(struct IOExtSer)))
{
if(WriteRequest = (struct IOExtSer *)AllocVec(sizeof(struct IOExtSer),MEMF_ANY | MEMF_PUBLIC))
{
if(!OpenDevice((UBYTE *)Channel,Unit,(struct IORequest *)ReadRequest,NULL))
{
ReadRequest->IOSer.io_Command = SDCMD_SETPARAMS;
ReadRequest->io_ExtFlags = 0;
ReadRequest->io_ReadLen = 8;
ReadRequest->io_WriteLen = 8;
ReadRequest->io_StopBits = 1;
if(Baud)
ReadRequest->io_Baud = Baud;
if(RTS_CTS >= FALSE)
{
if(RTS_CTS)
ReadRequest->io_SerFlags = (UBYTE)( ReadRequest->io_SerFlags | SERF_XDISABLED | SERF_7WIRE);
else
ReadRequest->io_SerFlags = (UBYTE)((ReadRequest->io_SerFlags | SERF_XDISABLED) & ~SERF_7WIRE);
}
else
ReadRequest->io_SerFlags |= SERF_XDISABLED;
if(!DoIO((struct IORequest *)ReadRequest))
{
CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
WriteRequest->IOSer.io_Message.mn_ReplyPort = WritePort;
if(TimePort = CreateMsgPort())
{
TimeMask = 1UL << TimePort->mp_SigBit;
if(TimeRequest = (struct timerequest *)CreateIORequest(TimePort,sizeof(struct timerequest)))
{
if(!OpenDevice((UBYTE *)TIMERNAME,UNIT_VBLANK,(struct IORequest *)TimeRequest,NULL))
{
Valid = TRUE;
StartRead();
return(0);
}
DeleteIORequest((struct IORequest *)TimeRequest);
TimeRequest = NULL;
}
DeleteMsgPort(TimePort);
TimePort = NULL;
}
}
CloseDevice((struct IORequest *)ReadRequest);
}
FreeVec(WriteRequest);
WriteRequest = NULL;
}
DeleteIORequest((struct IORequest *)ReadRequest);
ReadRequest = NULL;
}
DeleteMsgPort(WritePort);
WritePort = NULL;
}
DeleteMsgPort(ReadPort);
ReadPort = NULL;
}
return(-1);
}
LONG IORawSerial::GetChar(LONG Timeout)
{
LONG Result;
if(Valid)
{
if(Reading)
{
if(CheckIO((struct IORequest *)ReadRequest))
{
if(WaitRead())
Result = CHANNELERR_Nothing;
else
Result = SingleChar;
StartRead();
}
else
{
if(Timeout)
{
ULONG Signals;
StartTime(Timeout);
for(;;)
{
Signals = ::Wait(ReadMask | TimeMask);
if(Signals & ReadMask)
{
if(WaitRead())
Result = CHANNELERR_Nothing;
else
Result = SingleChar;
StopTime();
StartRead();
break;
}
if(Signals & TimeMask)
{
WaitTime();
Result = CHANNELERR_Timeout;
break;
}
}
}
else
Result = CHANNELERR_Nothing;
}
}
else
Result = CHANNELERR_Nothing;
}
else
Result = CHANNELERR_EOF;
return(Result);
}
VOID IORawSerial::PutString(CONST STRPTR String,LONG Len)
{
if(Valid)
{
if(Len < 0)
Len = strlen(String);
WriteRequest->IOSer.io_Command = CMD_WRITE;
WriteRequest->IOSer.io_Data = (APTR)String;
WriteRequest->IOSer.io_Length = Len;
DoIO((struct IORequest *)WriteRequest);
}
}
LONG IORawSerial::Waiting(VOID)
{
if(Valid)
{
if(Reading)
{
if(CheckIO((struct IORequest *)ReadRequest))
return(1);
}
WriteRequest->IOSer.io_Command = SDCMD_QUERY;
DoIO((struct IORequest *)WriteRequest);
return((LONG)WriteRequest->IOSer.io_Actual);
}
else
return(0);
}
ULONG IORawSerial::WaitMask(VOID)
{
return(ReadMask);
}
VOID IORawSerial::Wait(LONG Seconds)
{
TimeRequest->tr_node.io_Command = TR_ADDREQUEST;
TimeRequest->tr_time.tv_secs = Seconds;
TimeRequest->tr_time.tv_micro = 0;
DoIO((struct IORequest *)TimeRequest);
}
IORawSerial::IORawSerial()
{
Reading = Ticking = Valid = FALSE;
}
IORawSerial::~IORawSerial()
{
Close();
}
VOID IORawSerial::StartTime(ULONG Seconds,ULONG Micros)
{
StopTime();
TimeRequest->tr_node.io_Command = TR_ADDREQUEST;
TimeRequest->tr_time.tv_secs = Seconds;
TimeRequest->tr_time.tv_micro = Micros;
SetSignal(0,TimeMask);
SendIO((struct IORequest *)TimeRequest);
Ticking = TRUE;
}
VOID IORawSerial::StopTime(VOID)
{
if(Ticking)
{
if(!CheckIO((struct IORequest *)TimeRequest))
AbortIO((struct IORequest *)TimeRequest);
WaitTime();
}
}
VOID IORawSerial::WaitTime(VOID)
{
if(Ticking)
{
WaitIO((struct IORequest *)TimeRequest);
Ticking = FALSE;
}
}
VOID IORawSerial::Flush(VOID)
{
if(Valid)
{
BOOL IsReading = Reading;
StopRead();
WriteRequest->IOSer.io_Command = CMD_CLEAR;
DoIO((struct IORequest *)WriteRequest);
if(IsReading)
StartRead();
}
}